package com.yaodian100.ec.product.service;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.DomainService;
import com.yaodian100.ec.product.entity.AddOnProduct;
import com.yaodian100.ec.product.entity.AddOnProductPage;
import com.yaodian100.ec.product.entity.Brand;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.ProductCategory;
import com.yaodian100.ec.product.entity.ProductPromotionFlag;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.entity.SpecificationMajor;
import com.yaodian100.ec.product.entity.ViewPickProduct;
import com.yaodian100.ec.product.entity.VirtualProduct;
import com.yaodian100.ec.shelf.entity.Shelf;
import com.yaodian100.ec.supplierapply.entity.SupplierApply;

public interface ProductService extends DomainService<Product> {

	/**
	 * 复制商品
	 * 
	 * @param product
	 * @param productPromotionFlag
	 * @return
	 * @throws CoreException
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	public Product copyProduct(String copyProductId) throws CoreException, IllegalAccessException,
			InvocationTargetException;

	public void delBrand(Brand brand) throws CoreException;

	// 检查该商品是否已售完
	public void checkIsSoldOut(String ProductId) throws CoreException;

	public boolean deleteProductCategory(String[] id) throws CoreException;

	public void delProductCategory(ProductCategory productCategory) throws CoreException;

	public void delProductPromotionFlag(ProductPromotionFlag productPromotionFlag) throws CoreException;

	public void delVirtualProduct(VirtualProduct virtualProduct) throws CoreException;

	public AddOnProduct getAddOnProduct(String mainProductId, String addOnProductId) throws CoreException;

	public AddOnProduct getAddOnProductById(Long addOnId) throws CoreException;

	public List<AddOnProduct> getAddOnProductList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	public List<String> getAddOnProductList(String mainProductId, String addOnProductId, String status, int firstResult,
			int maxResults) throws CoreException;

	public Number getAddOnProductListSize(String mainProductId, String addOnProductId, String status)
			throws CoreException;

	/**
	 * 回传有效的 addOnProduct. mainProductId=${mainProductId} and isEnable="Y" and isDelete="N" and startDate<=now and
	 * endDate>=now
	 * 
	 * @param mainProductId
	 * @return Map<AddOnProduct.addOnProductId, AddOnProduct>
	 * @throws CoreException
	 */
	public Map<String, AddOnProduct> getAddOnProducts(String mainProductId, boolean nmProduct) throws CoreException;

	public Brand getBrandByBrandId(String brandId) throws CoreException;

	public List<Brand> getBrandList(int firstResult, int maxResults, CommonCriteria criteria, String[] sortOrder)
			throws CoreException;

	public ProductCategory getProductCategory(Long id) throws CoreException;

	/**
	 * 依館id查詢在該館的所有商品
	 * 
	 * @param categoryId
	 * @return
	 * @throws CoreException
	 */
	public List<Object> getProductCategoryByCategoryId(Long categoryId, String isDelete) throws CoreException;

	/**
	 * 取得商品上架目錄清單
	 * 
	 * @param productId
	 * @return mapEntity.key 為 categoryId
	 * @throws CoreException
	 */
	public Map<String, ProductCategory> getProductCategoryByProduct(String productId) throws CoreException;

	public List<ProductCategory> getProductCategoryList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	public List getProductIds(int firstResult, int maxResults, CommonCriteria criteria, String[] sortOrder)
			throws CoreException;

	public List<Product> getProductOnShelfPageableList(String prodId, String prodName, String prodType, String prodAttr,
			String supplierId, String categoryPath, String productBrand, int firstResult, int maxResults)
			throws CoreException;

	public Number getProductOnShelfPageableListSize(String prodId, String prodName, String prodType, String prodAttr,
			String supplierId, String categoryPath, String productBrand);

	public ProductPromotionFlag getProductPromotionFlag(String productId) throws CoreException;

	public List<ProductPromotionFlag> getProductPromotionFlagList(int firstResult, int maxResults,
			CommonCriteria criteria, String[] sortOrder) throws CoreException;

	public String getProposeProductIdNo() throws CoreException;

	/**
	 * @param specId
	 * @return
	 * @throws CoreException
	 */
	public Specification getSpecification(Long specId) throws CoreException;

	public List<SpecificationInventory> getSpecificationInventory(CommonCriteria criteria) throws CoreException;

	public SpecificationInventory getSpecificationInventory(String productId, Long specId) throws CoreException;

	public Map<String, String> getSpecificationinventoryDaoSum(List products) throws CoreException;

	public Map<String, SpecificationInventory> getSpecificationInventoryMap(String productId) throws CoreException;

	public List<Specification> getSpecificationList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	/**
	 * @param productId
	 * @return
	 * @throws CoreException
	 */
	public Map<String, Specification> getSpecifications(String productId) throws CoreException;

	public List<Object> getStockOutReport(Long categoryId, String isDelete, String pmId, String productId,
			String productName, String supplier, boolean stockNotify, int startStockQty, int endStockQty)
			throws CoreException;

	public List<SupplierApply> getSupplierApplyList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	/**
	 * 查询ｎ选ｍ商品
	 * 
	 * @param firstResult
	 * @param maxResults
	 * @param criteria
	 * @param sortOrder
	 * @return
	 * @throws CoreException
	 */
	public List<ViewPickProduct> getViewPickProductList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	/**
	 * 取得n选m商品笔数
	 * 
	 * @param criteria
	 * @return
	 * @throws CoreException
	 */
	public Number getViewPickProductListSize(CommonCriteria criteria) throws CoreException;

	public List<VirtualProduct> getVirtualProductList(int firstResult, int maxResults, CommonCriteria criteria,
			String[] sortOrder) throws CoreException;

	/* 立即購買 */
	public ArrayList<String> orderBuyNowInfo(String[] itemNo, String[] specNo, String[] qty, String[] categoryPath,
			String[] type, String presents, String addOns) throws CoreException;

	public String readBrandFromFile(String brandId) throws CoreException;

	/** 將brief,description,details 檔案讀出 */
	public String readFromFile(String productId, String contextType) throws CoreException;

	/**
	 * 读取default馆别的购物须知檔
	 * 
	 * @param categoryId
	 * @return
	 * @throws CoreException
	 */
	public String readOrderNotice(String categoryId) throws CoreException;

	/* 搭售 / 加價購 / 贈品 / 加一元多一件 */
	public void saveAddOnProduct(AddOnProduct addOnProduct) throws CoreException;

	/* 品牌資料 */
	public Brand saveBrand(Brand brand) throws CoreException;

	public void saveBrandToFile(String brandId, String context) throws CoreException;

	/**
	 * 搭售 / 加價購 / 贈品 / 加一元多一件批次更新
	 * 
	 * @param addOnProducts
	 * @throws CoreException
	 */
	public boolean saveOrUpdateAddOnProductBatch(List<AddOnProduct> addOnProducts, List<AddOnProduct> removeProducts)
			throws CoreException;

	/**
	 * 新 增/修改商品主檔
	 * 
	 * @param entity
	 * @return
	 * @throws CoreException
	 */
	public Product saveOrUpdateProduct(Product product, ProductPromotionFlag productPromotionFlag) throws CoreException;

	public Product saveOrUpdateProductByPickProduct(Product product, ProductPromotionFlag productPromotionFlag,
			Shelf shelf) throws CoreException, IllegalAccessException, InvocationTargetException;

	public boolean saveOrUpdateProductCategoryBatch(Product product, List<ProductCategory> productCategories)
			throws CoreException;

	/**
	 * 新增/修改 n选m上架檔资料
	 * 
	 * @param shelf
	 * @param product
	 * @return
	 * @throws CoreException
	 */
	public Shelf saveOrUpdateShelfByPickProduct(Shelf shelf, Product product) throws CoreException;

	public void saveProductCategory(ProductCategory productCategory) throws CoreException;

	/* 商品前台促銷設定檔 */
	public void saveProductPromotionFlag(ProductPromotionFlag productPromotionFlag) throws CoreException;

	public void saveSpecification(Specification specification) throws CoreException;

	public void saveSpecificationInventory(SpecificationInventory specificationInventory) throws CoreException;

	public void saveSpecificationInventoryAndInvalid(SpecificationInventory specificationInventory, String invHistoryId)
			throws CoreException;

	public void saveVirtualProduct(VirtualProduct virtualProduct) throws CoreException;

	public Product updateNoSync(Product entity) throws CoreException;

	public void saveBatchSpecification(String productId, List<Specification> newSpecs, List<Specification> updSpecs,
			List<Specification> delSpecs) throws CoreException;

	/**
	 * 修改n选m商品
	 * 
	 * @param entity
	 * @return
	 * @throws CoreException
	 */
	public Product updatePickProduct(Product entity) throws CoreException;

	public boolean updateProductCategory(String[] id, String showSeq[]) throws CoreException;

	public boolean updateProductCategory(String[] id, String categoryId, String func) throws CoreException;

	public boolean chkProductHasInventory(Product mainProduct);

	public boolean saveOrUpdateMainProductCategoryBatch(List<Product> products, String oldCateId, String newCateId,
			boolean delOldCateId) throws CoreException;

	public int getStockOutByProductId(String productId);

	/**
	 * 批次商品成本異動
	 * 
	 * @param productId[],cost[]
	 * @return
	 */
	public String updateProductCostArray(String[] productId, BigDecimal[] cost) throws CoreException;

	// public void saveToFile(String productId, String context, String contextType);
	/**
	 * 批次修改商品採購模式為BO
	 * 
	 * @param supplierId
	 * @return
	 * @throws CoreException
	 */
	public boolean updateIsScmToBOBatch(String supplierId) throws CoreException;

	// 已销售未出货的库存查询
	public List<Object> orderNotShipping(String productId, String specId) throws Exception;

	public int getProductCategoryCountByCategoryId(Long categoryId, List<String> isDelete, String keyword,
			boolean isCheckPrice);

	public boolean publishProdCat(String categoryIdParam);

	public boolean delProdCat(String[] delProductCategoryIds);

	public Object[] getProductCategoryByCategoryIdPager(Long categoryId, List<String> isDelete, String keyword,
			Integer startAt, Integer maxRow, boolean isCheckPrice) throws CoreException;

	public List<Object> getProductCategoryByCategoryId(Long categoryId, List<String> isDelete) throws CoreException;

	/**
	 * 商品頁搜尋條件
	 * 
	 * @param searchMap
	 * @param firstResult
	 * @param maxResults
	 * @return
	 * @throws CoreException
	 */
	public List<Product> getProductPageableList(Map<String, String> searchMap, int firstResult, int maxResults)
			throws CoreException;

	/**
	 * 商品頁搜尋條件筆數
	 * 
	 * @param searchMap
	 * @return
	 * @throws CoreException
	 */
	public Number getProductPageableListSize(Map<String, String> searchMap) throws CoreException;

	public Number getProductAttrListSize(List productIds, String productName, String sort_promoteName,
			String categoryPath, Map eqData, Map neData, Map inData, Boolean hasShelf) throws CoreException;

	public List getProductAttrList(List productIds, String productName, String categoryPath, Map eqData, Map neData,
			Map inData, Boolean hasShelf, int firstResult, int maxResults, String[] sortBy) throws CoreException;

	/**
	 * 不區分大小寫的搜尋方式
	 * 
	 * @param firstResult
	 * @param maxResults
	 * @param nameParam 英文名稱
	 * @param statusParam 品牌狀態
	 * @return
	 */
	public List<Brand> getBrandList(int firstResult, int maxResults, String nameParam, String statusParam);

	/**
	 * 
	 * @param criteria
	 * @return
	 */
	public Number getBrandListSize(CommonCriteria criteria);

	/**
	 * @param productIds
	 * @param productName
	 * @param categoryPath
	 * @param eqData
	 * @param neData
	 * @param inData
	 * @param hasShelf
	 * @param firstResult
	 * @param maxResults
	 * @param sortBy
	 * @return
	 * @throws CoreException
	 */
	public List<Object[]> getProductAttrListForShelf(List productIds, String productName, String sort_promoteName,
			String categoryPath, Map eqData, Map neData, Map inData, Boolean hasShelf, int firstResult, int maxResults,
			String[] sortBy) throws CoreException;

	/**
	 * 依主商品查詢搭售商品的SPEC(赠品、搭售、n选m)
	 * 
	 * @param productId
	 * @return
	 */
	public Map<String, List<Specification>> getAddonProductSpecifciation(Product product);

	/**
	 * 依主商品查询赠品与加购商品
	 * 
	 * @param productId
	 * @return
	 */
	public Map<String, List<AddOnProductPage>> getAddonProductByMainProduct(Product product);

	/**
	 * 依主商品查詢搭售商品的庫存數(赠品、搭售、n选m)
	 * 
	 * @param productId
	 * @return
	 */
	public Map<String, Map<Long, Integer>> getAddonProductInvByMainProduct(Product product);

	/**
	 * 依主商品查詢搭售商品的双属性(赠品、搭售、n选m)
	 * 
	 * @param productId
	 * @return
	 */
	public Map<String, List<SpecificationMajor>> getAddonProductSpecificationMajor(Product product);
}
